using System;
using Server;
using Server.Multis;
using Server.Mobiles;
using Server.Targeting;

namespace Server.Items
{
    [FlipableAttribute(0x1EBA, 0x1EBB)]
    public class TaxidermyKit : Item
    {
        public override int LabelNumber { get { return 1041279; } } // a taxidermy kit

        [Constructable]
        public TaxidermyKit()
            : base(0x1EBA)
        {
            Weight = 1.0;
        }

        public TaxidermyKit(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (!IsChildOf(from.Backpack))
            {
                from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
            }
            else if (from.Skills[SkillName.Carpentry].Base < 90.0)
            {
                from.SendLocalizedMessage(1042594); // You do not understand how to use this.
            }
            else
            {
                from.SendLocalizedMessage(1042595); // Target the corpse to make a trophy out of.
                from.Target = new CorpseTarget(this);
            }
        }

        private static object[,] m_Table = new object[,]
			{
				{ typeof( BrownBear ),		0x1E60,		1041093, 1041107 },
				{ typeof( GreatHart ),		0x1E61,		1041095, 1041109 },
				{ typeof( Gorilla ),		0x1E63,		1041091, 1041105 },
				{ typeof( Orc ),			0x1E64,		1041090, 1041104 },
				{ typeof( PolarBear ),		0x1E65,		1041094, 1041108 },
				{ typeof( Troll ),			0x1E66,		1041092, 1041106 }
			};

        private class CorpseTarget : Target
        {
            private TaxidermyKit m_Kit;

            public CorpseTarget(TaxidermyKit kit)
                : base(3, false, TargetFlags.None)
            {
                m_Kit = kit;
            }

            protected override void OnTarget(Mobile from, object targeted)
            {
                if (m_Kit.Deleted)
                    return;

                if (!(targeted is Corpse) && !(targeted is Fish))
                {
                    from.SendLocalizedMessage(1042600); // That is not a corpse!
                }
                else if (targeted is Corpse && ((Corpse)targeted).VisitedByTaxidermist)
                {
                    from.SendLocalizedMessage(1042596); // That corpse seems to have been visited by a taxidermist already.
                }
                else if (!m_Kit.IsChildOf(from.Backpack))
                {
                    from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
                }
                else if (from.Skills[SkillName.Carpentry].Base < 90.0)
                {
                    from.SendLocalizedMessage(1042603); // You would not understand how to use the kit.
                }
                else
                {
                    object obj = targeted;

                    if (obj is Corpse)
                        obj = ((Corpse)obj).Owner;

                    for (int i = 0; obj != null && i < m_Table.GetLength(0); ++i)
                    {
                        if ((Type)m_Table[i, 0] == obj.GetType())
                        {
                            Container pack = from.Backpack;

                            if (pack != null && pack.ConsumeTotal(typeof(Board), 10))
                            {
                                from.SendLocalizedMessage(1042278); // You review the corpse and find it worthy of a trophy.
                                from.SendLocalizedMessage(1042602); // You use your kit up making the trophy.

                                Mobile hunter = null;
                                int weight = 0;

                                from.AddToBackpack(new TrophyDeed((int)m_Table[i, 1] + 7, (int)m_Table[i, 1], (int)m_Table[i, 2], (int)m_Table[i, 3], hunter, weight));

                                if (targeted is Corpse)
                                    ((Corpse)targeted).VisitedByTaxidermist = true;

                                m_Kit.Delete();
                                return;
                            }
                            else
                            {
                                from.SendLocalizedMessage(1042598); // You do not have enough boards.
                                return;
                            }
                        }
                    }

                    from.SendLocalizedMessage(1042599); // That does not look like something you want hanging on a wall.
                }
            }
        }
    }

    public class TrophyAddon : Item, IAddon
    {
        public override bool ForceShowProperties { get { return ObjectPropertyList.Enabled; } }

        private int m_WestID;
        private int m_NorthID;
        private int m_DeedNumber;
        private int m_AddonNumber;

        private Mobile m_Hunter;
        private int m_AnimalWeight;

        [CommandProperty(AccessLevel.GameMaster)]
        public int WestID { get { return m_WestID; } set { m_WestID = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int NorthID { get { return m_NorthID; } set { m_NorthID = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int DeedNumber { get { return m_DeedNumber; } set { m_DeedNumber = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int AddonNumber { get { return m_AddonNumber; } set { m_AddonNumber = value; InvalidateProperties(); } }

        public override int LabelNumber { get { return m_AddonNumber; } }

        [Constructable]
        public TrophyAddon(Mobile from, int itemID, int westID, int northID, int deedNumber, int addonNumber)
            : this(from, itemID, westID, northID, deedNumber, addonNumber, null, 0)
        {
        }

        public TrophyAddon(Mobile from, int itemID, int westID, int northID, int deedNumber, int addonNumber, Mobile hunter, int animalWeight)
            : base(itemID)
        {
            m_WestID = westID;
            m_NorthID = northID;
            m_DeedNumber = deedNumber;
            m_AddonNumber = addonNumber;

            m_Hunter = hunter;
            m_AnimalWeight = animalWeight;

            Movable = false;

            MoveToWorld(from.Location, from.Map);
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);

            if (m_AnimalWeight >= 20)
            {
                if (m_Hunter != null)
                    list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~

                list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones
            }
        }

        public TrophyAddon(Serial serial)
            : base(serial)
        {
        }

        public bool CouldFit(IPoint3D p, Map map)
        {
            if (!map.CanFit(p.X, p.Y, p.Z, this.ItemData.Height))
                return false;

            if (this.ItemID == m_NorthID)
                return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // North wall
            else
                return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // West wall
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version

            writer.Write((Mobile)m_Hunter);
            writer.Write((int)m_AnimalWeight);

            writer.Write((int)m_WestID);
            writer.Write((int)m_NorthID);
            writer.Write((int)m_DeedNumber);
            writer.Write((int)m_AddonNumber);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
                        m_Hunter = reader.ReadMobile();
                        m_AnimalWeight = reader.ReadInt();
                        goto case 0;
                    }
                case 0:
                    {
                        m_WestID = reader.ReadInt();
                        m_NorthID = reader.ReadInt();
                        m_DeedNumber = reader.ReadInt();
                        m_AddonNumber = reader.ReadInt();
                        break;
                    }
            }

            Timer.DelayCall(TimeSpan.Zero, new TimerCallback(FixMovingCrate));
        }

        private void FixMovingCrate()
        {
            if (this.Deleted)
                return;

            if (this.Movable || this.IsLockedDown)
            {
                Item deed = this.Deed;

                if (this.Parent is Item)
                {
                    ((Item)this.Parent).AddItem(deed);
                    deed.Location = this.Location;
                }
                else
                {
                    deed.MoveToWorld(this.Location, this.Map);
                }

                Delete();
            }
        }

        public Item Deed
        {
            get { return new TrophyDeed(m_WestID, m_NorthID, m_DeedNumber, m_AddonNumber, m_Hunter, m_AnimalWeight); }
        }

        public override void OnDoubleClick(Mobile from)
        {
            BaseHouse house = BaseHouse.FindHouseAt(this);

            if (house != null && house.IsCoOwner(from))
            {
                if (from.InRange(GetWorldLocation(), 1))
                {
                    from.AddToBackpack(this.Deed);
                    Delete();
                }
                else
                {
                    from.SendLocalizedMessage(500295); // You are too far away to do that.
                }
            }
        }
    }

    [Flipable(0x14F0, 0x14EF)]
    public class TrophyDeed : Item
    {
        private int m_WestID;
        private int m_NorthID;
        private int m_DeedNumber;
        private int m_AddonNumber;

        private Mobile m_Hunter;
        private int m_AnimalWeight;

        [CommandProperty(AccessLevel.GameMaster)]
        public int WestID { get { return m_WestID; } set { m_WestID = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int NorthID { get { return m_NorthID; } set { m_NorthID = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int DeedNumber { get { return m_DeedNumber; } set { m_DeedNumber = value; InvalidateProperties(); } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int AddonNumber { get { return m_AddonNumber; } set { m_AddonNumber = value; } }

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Hunter { get { return m_Hunter; } set { m_Hunter = value; InvalidateProperties(); } }

        [CommandProperty(AccessLevel.GameMaster)]
        public int AnimalWeight { get { return m_AnimalWeight; } set { m_AnimalWeight = value; InvalidateProperties(); } }

        public override int LabelNumber { get { return m_DeedNumber; } }

        [Constructable]
        public TrophyDeed(int westID, int northID, int deedNumber, int addonNumber)
            : this(westID, northID, deedNumber, addonNumber, null, 0)
        {
        }

        public TrophyDeed(int westID, int northID, int deedNumber, int addonNumber, Mobile hunter, int animalWeight)
            : base(0x14F0)
        {
            m_WestID = westID;
            m_NorthID = northID;
            m_DeedNumber = deedNumber;
            m_AddonNumber = addonNumber;
            m_Hunter = hunter;
            m_AnimalWeight = animalWeight;
        }

        public TrophyDeed(Serial serial)
            : base(serial)
        {
        }

        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);

            if (m_AnimalWeight >= 20)
            {
                if (m_Hunter != null)
                    list.Add(1070857, m_Hunter.Name); // Caught by ~1_fisherman~

                list.Add(1070858, m_AnimalWeight.ToString()); // ~1_weight~ stones
            }
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // version

            writer.Write((Mobile)m_Hunter);
            writer.Write((int)m_AnimalWeight);

            writer.Write((int)m_WestID);
            writer.Write((int)m_NorthID);
            writer.Write((int)m_DeedNumber);
            writer.Write((int)m_AddonNumber);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
                        m_Hunter = reader.ReadMobile();
                        m_AnimalWeight = reader.ReadInt();
                        goto case 0;
                    }
                case 0:
                    {
                        m_WestID = reader.ReadInt();
                        m_NorthID = reader.ReadInt();
                        m_DeedNumber = reader.ReadInt();
                        m_AddonNumber = reader.ReadInt();
                        break;
                    }
            }
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (IsChildOf(from.Backpack))
            {
                BaseHouse house = BaseHouse.FindHouseAt(from);

                if (house != null && house.IsCoOwner(from))
                {
                    bool northWall = BaseAddon.IsWall(from.X, from.Y - 1, from.Z, from.Map);
                    bool westWall = BaseAddon.IsWall(from.X - 1, from.Y, from.Z, from.Map);

                    if (northWall && westWall)
                    {
                        switch (from.Direction & Direction.Mask)
                        {
                            case Direction.North:
                            case Direction.South: northWall = true; westWall = false; break;

                            case Direction.East:
                            case Direction.West: northWall = false; westWall = true; break;

                            default: from.SendMessage("Turn to face the wall on which to hang this trophy."); return;
                        }
                    }

                    int itemID = 0;

                    if (northWall)
                        itemID = m_NorthID;
                    else if (westWall)
                        itemID = m_WestID;
                    else
                        from.SendLocalizedMessage(1042626); // The trophy must be placed next to a wall.

                    if (itemID > 0)
                    {
                        house.Addons.Add(new TrophyAddon(from, itemID, m_WestID, m_NorthID, m_DeedNumber, m_AddonNumber, m_Hunter, m_AnimalWeight));
                        Delete();
                    }
                }
                else
                {
                    from.SendLocalizedMessage(502092); // You must be in your house to do this.
                }
            }
            else
            {
                from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
            }
        }
    }
}